﻿using System;
using Microsoft.VisualStudio.Modeling;

namespace Project.Co_DataTransformationPrototype
{
    internal partial class Co_DataTransformationPrototypeDocView
    {
        private DiagramForm container;

        /// <summary>
        /// Gets the window containing the DSL.
        /// Normally this is just the VS window, but we place our form inside it.
        /// </summary>
        public override System.Windows.Forms.IWin32Window Window
        {
            get
            {
                if (container == null)
                {
                    // Put the our own form inside the DSL window:
                    container = new DiagramForm(this, (System.Windows.Forms.Control)base.Window);
                }
                return container;
            }
        }

        /// <summary>
        /// Opens the window. 
        /// 
        /// This override registers listeners for the Add and Remove store events.
        /// Store events are called after the end of a store transaction (or an undo/redo) and are 
        /// used to keep things outside the store synchronized with changes inside the store.
        /// See http://msdn.microsoft.com/library/bb126250.aspx
        /// 
        /// Note: This method is a convenient place to register listeners, because all the links
        /// in the model and diagram have been set up after loading from file.
        /// An alternative place is DocData.OnDocumentLoaded().
        /// </summary>
        /// <returns></returns>
        protected override bool LoadView()
        {
            bool result = base.LoadView();
            Logger logger = EventLogger.GetInstance();
            
            // Store events are added to the various properties of the EMD:
            Store store = this.DocData.Store;
            EventManagerDirectory emd = store.EventManagerDirectory;
            
            #region Transaction Event Handlers
            // Register the end of each event (which could contain multiple events)
            emd.TransactionCommitted.Add(new EventHandler<TransactionCommitEventArgs>(logger.transactionCommited));
            emd.TransactionRolledBack.Add(new EventHandler<TransactionRollbackEventArgs>(logger.transactionRolledback));
            #endregion

            #region Entity Event Handlers
            // Store events are registered per domain class, not per instance. After a listener is 
            // registered with a class, it is called for every change to any instance of the class
            DomainClassInfo entityInfo = store.DomainDataDirectory.FindDomainClass(typeof(Entity));
            emd.ElementAdded.Add(entityInfo, new EventHandler<ElementAddedEventArgs>(logger.elementAdded));
            emd.ElementDeleted.Add(entityInfo, new EventHandler<ElementDeletedEventArgs>(logger.elementRemoved));
            // Set one handler for all properties of a class
            emd.ElementPropertyChanged.Add(entityInfo, new EventHandler<ElementPropertyChangedEventArgs>(logger.elementUpdated));
            #endregion

            #region Relationship Event Handlers
            DomainRelationshipInfo linkInfo = store.DomainDataDirectory.FindDomainRelationship(typeof(EntityAssociation));
            emd.ElementAdded.Add(linkInfo, new EventHandler<ElementAddedEventArgs>(logger.linkAdded));
            emd.ElementDeleted.Add(linkInfo, new EventHandler<ElementDeletedEventArgs>(logger.linkRemoved));
            emd.ElementPropertyChanged.Add(linkInfo, new EventHandler<ElementPropertyChangedEventArgs>(logger.linkUpdated));
            #endregion
            
            #region Attribute Event Handlers
            DomainClassInfo attributeInfo = store.DomainDataDirectory.FindDomainClass(typeof(EntityAttribute));
            emd.ElementAdded.Add(attributeInfo, new EventHandler<ElementAddedEventArgs>(logger.attributeAdded));
            emd.ElementDeleted.Add(attributeInfo, new EventHandler<ElementDeletedEventArgs>(logger.attributeRemoved));
            emd.ElementPropertyChanged.Add(attributeInfo, new EventHandler<ElementPropertyChangedEventArgs>(logger.attributeUpdated));
            #endregion

            return result;
        }     
 
    }        
}
